/**
 * 图片的重新绘制并且颜色替换
 */
const handleCanvas = ({
	src, // 原图。可以是字符串数组或者字符串（带逗号的字符串只当做一个），依次加载。将以最后一张图的宽高为标准
	oldColor, // 原来需要替换的颜色值
	newColor = 'rgba(0, 0, 0, 0)', // 新图替换后的颜色值
	canvasId = 'myCanvas',
	that,
	callback
} = {}) => {
	const analyse = require('@/ui/form/input/analyse')
	oldColor = analyse(oldColor, 'color')
	newColor = analyse(newColor, 'color')
	return new Promise((resolve, reject) => {
		if (typeof(src) === 'string') {
			src = [src]
		}
		if (Array.isArray(src) && src.length > 0) {
			const arr = []
			const cycle = (index = 0) => {
				if (index < src.length) {
					uni.getImageInfo({
						src: src[index],
						success: (res) => {
							arr.push(res)
							cycle(index + 1)
						},
						fail: (err) => {
							console.error(err)
							cycle(index + 1)
						}
					})
				} else {
					if (arr.length > 0) {
						// 以最后一个的宽高为准
						const lastObj = arr[arr.length - 1]
						const {width, height} = lastObj
						if (callback) {
							callback(lastObj)
						}
						const params = {
							canvasId, x: 0, y: 0, width, height,
						}
						// 创建canvas
						const canvas = uni.createCanvasContext(canvasId, that)
						// 清空画布
						canvas.clearRect(0, 0, width, height)
						// 逐一加载图片
						const action = (i = 0) => {
							if (i < arr.length) {
								/**
								 * 绘制图片到canvas
								 * 取原图的中心附近的原比例图像区域。也就是说把原图缩放成宽高都刚好比最后一张图大或者相等
								 * 
								 * 先把宽度缩放为等宽
								 * 然后高度不小于标准
								 * 最后以中心点为标准取
								 */
								var sx = 0, sy = 0, sWidth = arr[i].width, sHeight = arr[i].height
								// 先把宽度缩放为等宽
								if (sWidth !== width) {
									sHeight = sHeight * width / sWidth
									sWidth = width
								}
								// 然后高度不小于标准
								if (sHeight < height) {
									sWidth = sWidth * height / sHeight
									sHeight = height
								}
								// 以中心点为标准取
								sx = (sWidth - width) * 0.5
								sx = (sHeight - height) * 0.5
								canvas.drawImage(arr[i].path, 0, 0, width, height, sx, sy, sWidth, sHeight)
								setTimeout(() => { // 延迟五秒再绘制下一张图
									action(i + 1)
								}, 500)
							} else {
								// 开始绘制
								canvas.draw(true, setTimeout(() => {
									// 获取图片像素数据
									uni.canvasGetImageData({
										...params,
										success: (res) => {
											const {data} = res
											if (oldColor && newColor) {
												// 新的颜色值
												const red = newColor[0].value, green = newColor[1].value, blue = newColor[2].value, alpha = newColor[3].value
												// 遍历像素数据，找到需要替换颜色的部分
												for (let i = 0; i < data.length; i += 4) {
													// 判断当前颜色是否为需要替换的颜色
													if (data[i] === oldColor[0].value && data[i + 1] === oldColor[1].value && data[i + 2] === oldColor[2].value && data[i + 3] === oldColor[3].value * 255) {
														// 替换为新的颜色
														data[i] = red // Red
														data[i + 1] = green // Green
														data[i + 2] = blue // Blue
														/**
														 * 原本是0~1，实际是0~255
														 * 所以要乘255
														 * 如果要改为透明。alpha为0无效，会恢复为原来的颜色。原因大概是有加上了新的一层画面，使透明的内容显示为未处理前的内容了
														 */
														data[i + 3] = alpha * 255 // Alpha
														if (alpha === 0) {
															canvas.clearRect((i / 4) % width, (i / 4) / width, 1, 1)
														}
													}
													/**
													 * 为什么第一行会有残留有一条线？处理掉
													 */
													if (alpha === 0) {
														if ((i / 4) < width) {
															canvas.clearRect(i / 4, 0, 1, 1)
														}
													}
												}
											}
											
											// 重新将修改后的像素数据放回canvas
											uni.canvasPutImageData({
												...params,
												data,
												success: (res) => {
													// 绘制完成后，将canvas转换为图片
													canvas.draw(true, setTimeout(() => {
														uni.canvasToTempFilePath({
															canvasId,
															success: (res) => {
																// 新的图片路径
																resolve(res.tempFilePath)
															},
															fail: (err) => {
																console.error(err)
																reject('最后绘制图片错误')
															}
														}, 100)
													}, 500))
												},
												fail: (err) => {
													console.error(err)
													reject('修改图片像素错误')
												}
											})
										},
										fail: (err) => {
											console.error(err)
											reject('获取图片像素错误')
										}
									}, that)
								}, 500))
							}
						}
						action()
						arr.map(item => {
							// 绘制图片到canvas
							canvas.drawImage(item.path, 0, 0, width, height)
						})
					} else {
						reject('图片解析完全失败')
					}
				}
			}
			cycle()
		} else {
			reject('没有图片链接')
		}
	})
}

module.exports = {
	handleCanvas
}